package thread

import (
	"strconv"
	"strings"
	"time"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/logger"

	"ssdevice/common/constant"
	"ssdevice/common/utils"
	"ssdevice/internal/device/models"
)

type DataDetailThread struct {
}

var detailTableName = models.SysDataDetail{}.TableName()

func (DataDetailThread) Run(threadName string) {
	logger.Infof("启动线程 - %s.", threadName)

	go func() {
		dataList := make([]models.SysDataDetail, 0)
		for {
			// 入库频率固定 慢点便于查询计算
			time.Sleep(10 * time.Minute)
			now := utils.GetNowTimeStr()
			// 设备数据条数
			for tp := range constant.DevDataCountCache.IterBuffered() {
				devSn := tp.Key
				count := tp.Val
				if count == 0 {
					continue
				}
				dataList = append(dataList, models.SysDataDetail{
					Type:             "DEV_DATA_NUM",
					Key:              devSn,
					Value:            count,
					CreateTimeInsStr: now,
				})
				// 置0重新计算
				constant.DevDataCountCache.Set(devSn, 0)
				if len(dataList) > constant.ThreadBatchSize {
					// 批量处理数据
					dealDataDetail(dataList)
					// 清空(减少扩容)
					dataList = dataList[0:0]
				}
			}
			// 设备数据大小
			for tp := range constant.DevDataSizeCache.IterBuffered() {
				devSn := tp.Key
				size := tp.Val
				if size == 0 {
					continue
				}
				dataList = append(dataList, models.SysDataDetail{
					Type:             "DEV_DATA_SIZE",
					Key:              devSn,
					Value:            size,
					CreateTimeInsStr: now,
				})
				// 置0重新计算
				constant.DevDataSizeCache.Set(devSn, 0)
				if len(dataList) > constant.ThreadBatchSize {
					// 批量处理数据
					dealDataDetail(dataList)
					// 清空(减少扩容)
					dataList = dataList[0:0]
				}
			}
			// 规则执行条数
			for tp := range constant.DevRuleCountCache.IterBuffered() {
				ruleId := tp.Key
				count := tp.Val
				if count == 0 {
					continue
				}
				dataList = append(dataList, models.SysDataDetail{
					Type:             "DEV_RULE_PROCS",
					Key:              ruleId,
					Value:            count,
					CreateTimeInsStr: now,
				})
				// 置0重新计算
				constant.DevRuleCountCache.Set(ruleId, 0)
				if len(dataList) > constant.ThreadBatchSize {
					// 批量处理数据
					dealDataDetail(dataList)
					// 清空(减少扩容)
					dataList = dataList[0:0]
				}
			}
			if len(dataList) > 0 {
				// 批量处理数据
				dealDataDetail(dataList)
				// 清空(减少扩容)
				dataList = dataList[0:0]
			}
		}
	}()
}

func dealDataDetail(dataList []models.SysDataDetail) {
	t1 := time.Now()
	//sysDataDetailModel := &models.SysDataDetail{}
	//sysDataDetailModel.Orm = env.Db
	//if err := sysDataDetailModel.Add(&dataList); err != nil {
	//	logger.Error(err)
	//}
	sql := "INSERT INTO " + detailTableName + " (type, key, value, create_time) VALUES "
	valueSql := make([]string, 0)
	for _, s := range dataList {
		valueSql = append(valueSql, "('"+s.Type+"','"+s.Key+"',"+strconv.Itoa(s.Value)+",'"+s.CreateTimeInsStr+"')")
	}
	sql += strings.Join(valueSql, ",")
	if err := env.Db.Raw(sql).Scan(&scan).Error; err != nil {
		logger.Error(err)
	}
	logger.Infof("data detail明细记录批量入库%d. 耗时%v", len(dataList), time.Since(t1).Round(time.Millisecond))
}
